home *** CD-ROM | disk | FTP | other *** search
- /* A Project is a network of Task and Milestone nodes to
- manage CPM or PERT networks. A project knows how to
- calculate its critical path, keep track of costs etc.
-
- Since Project descends from Network, it inherits all of
- Network's instance variables, e.g. start, end, name, desc.
- */!!
-
- inherit(Network, #Project, #(cost /* sum of all costs */
- resources /* used by tasks */
- autoCalc /* boolean is recalc on? */
-
- ), 2, nil)!!
-
- now(ProjectClass)!!
-
- now(Project)!!
-
- /* Return only the tasks in the project. */
- Def tasks(self)
- {
- ^extract(nodes(self),
- {using(node)
- class(node) <> Milestone;
- });
- }!!
-
- /* Returns a collection of lines summarizing useful information. */
- Def getInfoLines(self | tc)
- {
- tc := new(OrderedCollection, 6);
- add(tc, loadString(PW_PROJECT) + ": " + field(name, 8)+ " " + desc);
- add(tc, "");
- add(tc, loadString(PW_PROJT1));
- add(tc, "--------------------------------------------");
- add(tc, loadString(PW_START)
- + field(asString(getEarlyStart(self)), 8) + " "
- + field(asString(getLateStart(self)), 8) + " "
- + field(asString(getCost(self)), 6) + " "
- + field(asString(getTime(self)), 6) + " "
- + field(asString(getSlack(self)), 4));
- add(tc, loadString(PW_FINISH)
- + field(asString(getEarlyFinish(self)), 8) + " "
- + field(asString(getLateFinish(self)), 8));
- ^tc;
- }!!
-
- /* Return the resource if the name exists in the
- resources collection, otherwise return false and
- display an error message. */
- Def checkResExists(self, resName | res)
- {
- if not(res := resExists(self, resName))
- beep();
- errorBox(loadString(PW_RESINVAL),
- loadString(PW_RESOURCE) + " " + resName +
- loadString(PW_NOTEXIST));
- endif;
- ^res;
- }!!
-
- /* Return the resources collection. */
- Def resources(self)
- {
- ^resources;
- }!!
-
- /* Return the resource of the name resName if
- it exists, otherwise return false. Use
- checkResExists for error checking. */
- Def resExists(self, resName | res)
- {
- ^resName in resources;
- }!!
-
- /* Parse a string of resNames and return a set of
- resources. If the resource doesn't exist, a new
- one is created. */
- Def parseResNames(self, resNames | names, res, aRes)
- {
- names := words(resNames);
- res := new(OrderedCollection, 6);
- do(names,
- {using(name)
- if not(aRes := resExists(self, name)) /* create it */
- aRes := new(Resource);
- setName(aRes, name);
- if editInfo(aRes) == IDOK
- add(resources, getName(aRes), aRes);
- add(res, aRes);
- endif;
- else
- add(res, aRes);
- endif;
- });
- ^res;
- }!!
-
- /* Return a sorted collection of activities in the project.
- Sort by earlyStart, time, name for unique order.
- This uses early binding and dot notation for speed. */
- Def sortedActivities(self| sorted)
- {
- sorted := new(SortedCollection, 10);
-
- setCompareBlock(sorted, {using(a,b)
- if a.earlyStart = b.earlyStart
- if getTime(a) = getTime(b)
- a.name < b.name
- else
- getTime(a) < getTime(b)
- endif
- else
- a.earlyStart < b.earlyStart
- endif});
-
- do(nodeNames,
- {using(aNode)
- add(sorted:SortedCollection, aNode);
- });
- ^sorted;
- }!!
-
- /* Return the type of nodes that start and end should be.*/
- Def nodeClass(self)
- {
- ^Milestone;
- }!!
-
- /* Return the current cost which is always up to date. */
- Def getCost(self)
- {
- ^cost;
- }!!
-
- /* Get the user set late finish date. */
- Def getUserLateFinish(self)
- {
- ^getUserLateFinish(end);
- }!!
-
- /* Get the user set early start date. */
- Def getUserEarlyStart(self)
- {
- ^getUserEarlyStart(start);
- } !!
-
- /* Return a string to be used as a window caption. */
- Def makeCaption(self)
- {
- ^loadString(PW_PROJECT) + ": " + name;
- }!!
-
- /* Set the values of a project.
- Values is an array of name, desc,
- userEarlyStart, userLateFinish.
- This message is sent after editing. */
- Def setValues(self, values)
- {
- name := values[0];
- desc := values[1];
- if getEarlyStart(self) <> values[2]
- setEarlyStart(self, values[2]);
- endif;
- if getLateFinish(self) <> values[3]
- setLateFinish(self, values[3]);
- endif;
- }!!
-
- /* Display and edit the project information.
- The dialog should define methods run() and setEditItem().
- */
- Def editInfo(self | dlg, retValue)
- {
- showWaitCurs();
- dlg := new(ProjDialog);
- setEditItem(dlg, self);
- retValue := run(dlg, ThePort);
- showOldCurs();
- ^retValue;
- }!!
-
- /* Project slack is defined as the slack at the end node.
- This could be introduced if the user sets a lateFinish. */
- Def getSlack(self)
- {
- ^getSlack(end);
- }!!
-
- /* Return the current cost which is always up to date. */
- Def calcCost(self)
- {
- ^cost;
- }!!
-
- /* Update the cost based on a change to a Task. */
- Def updateCost(self, change)
- {
- cost := cost + change;
- }!!
-
- /* Do the backwards pass only starting from the end node.
- The end node is always critical.
- */
- Def recalc2(self)
- {
- recalc2(end);
- end.critical := true;
- }!!
-
- /* Turn automatic calculation on or off.
- Force recalculation if turned on. */
- Def setAutoCalc(self, mode)
- {
- if (autoCalc := mode) /* true or false */
- recalc(self);
- endif;
- }!!
-
- /* Recalculate the entire network. First invalidate all nodes
- so that a full recalc will be forced. Then do both the
- forward and backwards recalc passes. The forward pass must
- be entirely completed before doing the backwards pass. */
- Def recalc(self)
- {
- invalidate(start, new(Set,10)); /* clear all nodes */
- recalc1(start, true); /* force entire recalc */
- recalc2(self); /* backwards pass */
- }!!
-
- /* Get the project lateStart date. */
- Def getLateStart(self)
- {
- ^getLateStart(start);
- }!!
-
- /* Get the project earlyStart date. */
- Def getEarlyStart(self)
- {
- ^getEarlyStart(start);
- } !!
-
- /* Get the project early finish date. */
- Def getEarlyFinish(self)
- {
- ^getEarlyFinish(end);
- }!!
-
- /* Get the project late finish date. */
- Def getLateFinish(self)
- {
- ^getLateFinish(end);
- }!!
-
- /* Return the status of autoCalc mode. */
- Def autoCalc(self)
- {
- ^autoCalc;
- }!!
-
- /* The user can enter an early start date. */
- Def setEarlyStart(self, aDate)
- {
- setEarlyStart(start,aDate);
- }!!
-
- /* The user can enter a late finish date. */
- Def setLateFinish(self, aDate)
- {
- setLateFinish(end,aDate);
- }!!
-
- /* Calculate the project time. If negative (e.g. project
- isn't fully hooked up yet) return 0. */
- Def getTime(self)
- { ^max(0, getEarlyFinish(self) - getEarlyStart(self));
- }!!
-
- /* Initialize a new Project. Uses ancestor init.
- The nodeClass method determines the node type
- for start and end. */
- Def init(self)
- {
- init(self:Network); /* use ancestor init */
- cost := 0;
- resources := new(Dictionary, 10);
- setEarlyStart(start, /* set default project start */
- date(1,1,1988));
- }!!
-
-